

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    private static CopyOnWriteArrayList<Channel> group = new CopyOnWriteArrayList<Channel>();
    private static boolean isRunning = true;

    public static void main(String[] args) throws IOException {
        System.out.println("======server========");
        ServerSocket server = new ServerSocket(9999);
        ExecutorService es = Executors.newFixedThreadPool(100);
        
        while(isRunning){
            Socket s = server.accept();
            Channel c = new Channel(s);
            group.add(c);
            es.submit(new Thread(c));
        }
        es.shutdown();
    }


    static class Channel implements Runnable{
        private Socket client;
        private BufferedReader br;
        private PrintWriter pw;
        private boolean isRunning;
        private String name;
        private boolean isSys;

        public Channel(Socket s){
            this.client = s;
            isRunning = true;
            try{
                br = new BufferedReader(new InputStreamReader(client.getInputStream()));
                pw = new PrintWriter(new OutputStreamWriter(client.getOutputStream(), "GBK"), true);

                this.name = receive();
                this.send(name + "." + "欢迎您的到来");
                sendOther(this.name + "来到了聊天室", true);

            }catch(IOException e){

                release();
            }
        }

        @Override
        public void run(){

            while(isRunning){
                String datas = receive();
                if(!datas.equals("")){
                    sendOther(datas, false);
                }
            }
            release();
        }

        public String receive(){
            String msg = "";
            try{
                msg = br.readLine();
                System.out.println(msg);
            }catch(IOException e){
                System.out.println("接收信息错误");
                release();
            }
            return msg;
        }


        public void send(String msg){
            assert pw != null;
            try{
                pw.println(msg);
            }catch(Exception e){
                System.out.println("发送错误");
            }
        }

        public void sendOther(String msg, boolean isSys){
            boolean isPrivate = msg.startsWith("@");  // 私聊
            if(isPrivate){
                int idx = msg.indexOf(":");
                String targetName = msg.substring(1, idx);
                msg = msg.substring(idx + 1);

                for(Channel c : group){
                    if(c.name.equals(targetName)){
                        c.send(this.name + "悄悄地对你说： " +msg);
                        break;
                    }
                }
            }else{
                for(Channel c: group){
                    if(c == this) continue;
                    if(!isSys) c.send(this.name + "说： " + msg);
                    else c.send("系统消息： " + msg);
                }
            }

        }

        public void release(){
            if(isRunning){
				sendOther(this.name + "退出群聊", true);
                isRunning = false;
                Util.close(br, pw, client);
            }

        }


    }
}
